這個章節主要是介紹各種 “值” 在使用時,需要注意的地方。
Tony 覺得主要的重點在
(上)
(下)
與強型別的語言比較,JS的陣列只是容器。
var a = [1, "2" ,[3]];
a.lenght; // 3
a[0]; // 1
a[2][0]; // 3 都是取值的方法
不需要預設陣列的大小。宣告後,就可以新增 array 需要的值。
var a = [];
a[0] = 1;
a[1] = "2";
a[2] = [3];
a; // [1, "2", [3]];
但如果宣告的是稀疏(sparse)陣列,也就是缺了一格。她雖然會顯示 undefined,但不是真的 undefined。
var a = [];
a[0] = 1;
a[2] = [3];
a[1]; // undefined
a; //(3) [1, empty, Array(1)] 是 empty!
array 是用數值當索引,但他同時也是物件。
(所以他可以讓陣列多一個屬性,造成可以設 key 的假象。本身不算在 .length 之下。)
var a = [];
a[0] = 1;
a["foobar"] = 2;
a; // [1, foobar: 2]
a.length; //1
a["foobar"]; //2
a.foobar; //2
有趣的是,如果把數字的字串當引數用,會被強制轉型喔!
var a = [];
a["13"] = 1;
a.length; // 14
綜合以上,新增 key/value pair,請用物件別用陣列。
有時候會需要將類陣列的值,轉換成真正的陣列,藉由索引來遍歷。類陣列可能是,各種形式的串列(lists)或字串。
轉換串列成陣列的兩種方法。
function foo() {
var arr = Array.prototype.slice.call(arguments);
arr.push("bam");
console.log( arr );
}
foo( "bar", "baz"); // ["bar", "baz", "bam"]
var arr = Array.form( arguments );
[..."abc"]; // (3) ["a","b","c"]
JavaScript 的 String 實際上不等同字元所組成的陣列。
JS 更嚴格,陣列是可以隨意變更內容,字串是不可變的(immutable)。
var a = "foo";
var b = ["f","o","o"];
a[1] = "O";
b[1] = "O";
a; // "foo";
b; // ["f", "O", "o"];
a[1],在舊 IE 版本不能用,現在都可以用了。但比較正確的讀取是 a.charAt(1)。
因為字串不可變,如何變更? JS 會建立一個新的字串。
c = a.toUpperCase();
c === a; // false
a; // "foo"
c; // "FOO"
所以,string 會藉由使用 array 的方法作轉換。
a.join; // undefined
var c = Array.prototype.join.call( a, "-");
c; // "f-o-o"
但是,如果 array 的方法,會改變原始的 array。就不適用。
因為 string 是不可變 ( immutable ) 的。
a.reverse; // undefined;
var b = ["f","o","o"];
b.reverse(); // ["o", "o", "f"]
b; // ["o", "o", "f"]
這時如果將 string 轉成可變的 array,就會使一切變可能。
var c = a.split("").reverse().join("");
c; // "oof"
.split(""),會將 string 拆解成 array。.reverse() 反轉後,再用 .join("") 組合成字串。
綜合以上,如果字串很常做運算,請存成 array,需要顯示時加上 join 即可。
JavaScript 只有一個數值型別:number。這個型別包含了,整數(integer) 和 帶小數點的十進位數(fractional decimal numbers)。
JS 沒有真正的整數。因為 42 與 42.0 對 JS 來說都是整數,他們都是沒有小數點的十進位數。
JS 實作用的是 IEEE 754 標準。其中一項雙精度格式,搭配將二進位浮點數存到記憶體的方法,就實現了所有的 number 都是 十進位值。
參考資料
以下都是能成立的。
var a = 42;
var b = 42.3;
var c = 0.42;
var d = .42;
var e = 42.0;
var f = 42.; // 沒人在用,但是語法有效。
非常大或非常小的值,會以科學記號來呈現。
var a = 5E10;
a; // 50000000000
a.toExponential(); // "5e+10"
var b = a*a;
b; // 2.5e+21
var c = 1/a;
c; // 2e-11
number 可用 Number 物件包裹器來封裝,可以取用 Number.prototype 內建的方法。
(之後介紹 prototype 和物件,請再回想這裡發生的事)
可決定顯示 number 小數點後的位數。
var a = 42.5;
a.toFixed(-1); //uncaught error
a.toFixed(0); // "43"
a.toFixed(1); // "42.5"
a.toFixed(2); // "42.50"
可決定要顯示的位數。
不同於 .toFixed(),他的起始位置是從整個 number 開始計算。
var a = 42.5;
a.toPrecision(0); // uncaught error
a.toPrecision(1); // "4e+1"
a.toPrecision(2); // "43"
a.toPrecision(3); // "42.5"
a.toPrecision(4); // "42.50"
兩個方法都可以單行完成。
(42).toFixed(3); // "42.000"
0.42.toPrecision(3); // "0.42"
42..toFixed(3); // "42.000"
42 .toFixed(3); // "42.000" 請避免留空格做法。
42.toFixed(3); // SyntaxError
因為小數點會被先解讀為字面值,也就是 42. 的number。取用 toFixed(3) 方法的 .消失而造成錯誤。
不管哪個,直接用方法取用數值來顯示都是很少見的,是說也不代表好壞。
數值也可以用 16 進位,和 8 進位表示。
0xf3; // 16進位的243
0Xf3; // 同上
0o363; // 8進位的 243
0O363; // 同上,但請別把 O 放在 0 旁邊。
0b11110011; // 2進位的 243
0B11110011; // 同上
雖然都是會過的語法,但請都用小寫比較容易閱讀。
整個第五章打下來有 8xxx 多個字,標記和標點符號都算在內。
我打得很開心,希望你看的也很開心(咦?)。(第七章的量超多。)
源源不絕的知識正在灌進來啊!(加油~)
明天見。